package itv.java.web.util;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author : Son
 * @comment : file download Util
 */
public class FileDownload {

	// download buffer
	private static final int BUFFER_SIZE = 8192; // 8kb

	// character encodinf
	private static final String CHARSET = "utf-8";

	/**
	 * @comment : file download
	 */
	public static void download(HttpServletRequest request,
			HttpServletResponse response, File file) throws ServletException,
			IOException {

		String mimetype = request.getSession().getServletContext()
				.getMimeType(file.getName());

		if (file == null || !file.exists() || file.length() <= 0
				|| file.isDirectory()) {
			throw new IOException("This is not file.");
		}

		InputStream is = null;

		try {
			is = new FileInputStream(file);
			download(request, response, is, file.getName(), file.length(),
					mimetype);
		} finally {
			try {
				is.close();
			} catch (Exception ex) {
			}
		}
	}

	/**
	 * @comment : file download
	 */
	public static void download(HttpServletRequest request,
			HttpServletResponse response, InputStream is, String filename,
			long filesize, String mimetype) throws ServletException,
			IOException {

		String mime = mimetype;

		if (mimetype == null || mimetype.length() == 0) {
			mime = "application/octet-stream;";
		}

		byte[] buffer = new byte[BUFFER_SIZE];

		response.setContentType(mime + "; charset=" + CHARSET);

		String userAgent = request.getHeader("User-Agent");

		// attachment; 가 붙으면 IE의 경우 무조건 다운로드창이 뜬다. 상황에 따라 써야한다.
		if (userAgent != null && userAgent.indexOf("MSIE 5.5") > -1) { // MS IE
			// 5.5
			// under
			response.setHeader("Content-Disposition",
					"filename=" + URLEncoder.encode(filename, "UTF-8") + ";");
		} else if (userAgent != null && userAgent.indexOf("MSIE") > -1) { // MS
			// IE
			// (6.x
			// upper)
			response.setHeader("Content-Disposition", "attachment; filename="
					+ java.net.URLEncoder.encode(filename, "UTF-8") + ";");
		} else { // 모질라나 오페라
			response.setHeader("Content-Disposition", "attachment; filename="
					+ new String(filename.getBytes(CHARSET), "latin1") + ";");
		}

		// 파일 사이즈가 정확하지 않을때는 아예 지정하지 않는다.
		if (filesize > 0) {
			response.setHeader("Content-Length", "" + filesize);
		}

		BufferedInputStream fin = null;
		BufferedOutputStream outs = null;

		try {
			fin = new BufferedInputStream(is);
			outs = new BufferedOutputStream(response.getOutputStream());
			int read = 0;

			while ((read = fin.read(buffer)) != -1) {
				outs.write(buffer, 0, read);
			}
		} catch (IOException ex) {
			// Tomcat ClientAbortException을 잡아서 무시하도록 처리해주는게 좋다.
		} finally {
			try {
				outs.close();
			} catch (Exception ex1) {
			}

			try {
				fin.close();
			} catch (Exception ex2) {
			}
		}
	}
}